module control  (
    //  input
    opcode,MemRead_w,MemWrite_w,RegWrite_w,
    //  output
    RegDst,Jump,JR,Branch,MemRead,MemtoReg,MemWrite,
    ALUSrc1,ALUSrc2,RegWrite,sign_zero,ExtMux,wb_pc,PC_en
    );

    input   [4:0]   opcode;
    input           MemRead_w,MemWrite_w,RegWrite_w;
    output  [1:0]   RegDst;
    output          Jump,JR,Branch,MemRead,MemtoReg,MemWrite;
    output          ALUSrc1,ALUSrc2,RegWrite,sign_zero;
    output          ExtMux,wb_pc,PC_en;

    wire    a,b,c,d,e;
    assign  {a,b,c,d,e} = opcode;
    assign  RegDst[1] = (~a&(~b|~c))|(a&~c&~d&~e)|(~b&~c&d);
    assign  RegDst[0] = (~a&(~b|~c))|(a&b&c)|(a&b&~c&(d|e));
    assign  Jump = ~a&~b&c&~e;
    assign  JR = ~a&~b&c&e;
    assign  Branch = ~a&b&c;
    assign  MemRead = a&~b&~c&~d&e;
    assign  MemtoReg = MemRead;
    assign  MemWrite = a&~b&~c&(~d&~e | d&e);
    assign  ALUSrc1 = a&~b | b&~c&~d | ~a&b&~c | ~a&~b&c&e;
    assign  ALUSrc2 = ~a&~b&d;
    assign  RegWrite = b&~c | a&b | a&c | ~a&~b&d | a&e | a&d;
    assign  sign_zero = ~(~a&b&~c&d | a&~b&~c&d&~e);
    assign  ExtMux = ~a&b&c | a&b&~c | a&~b&~c&d&~e | ~a&~b&c&~d;
    assign  wb_pc = a&~b&~c&d&~e;
    assign  PC_en = | opcode;
    
endmodule
